package com.pay.ioopos;

import android.util.Log;

import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import okhttp3.ConnectionSpec;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class HttpUtil {
	private static final String TAG = HttpUtil.class.getSimpleName();
	private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
	private static SSLSocketFactory sslSocketFactory;
	
	public static String post(String serverPath, String postBody) throws Exception {
		if (Log.isLoggable(TAG, Log.DEBUG)) {
			Log.d(TAG,"请求地址：" + serverPath);
			Log.d(TAG,"请求内容：" + postBody);
		}

		OkHttpClient client = new OkHttpClient.Builder()
				.connectionSpecs(Arrays.asList(ConnectionSpec.CLEARTEXT, ConnectionSpec.COMPATIBLE_TLS))
				.sslSocketFactory(sslSocketFactory(), trustX509Manager())
				.callTimeout(20, TimeUnit.SECONDS)
				.connectTimeout(10, TimeUnit.SECONDS)
				.build();

		RequestBody body = RequestBody.create(postBody, JSON);
		Request request = new Request.Builder()
				.url(serverPath)
				.post(body)
				.build();
		String resBody;
		try (Response response = client.newCall(request).execute()) {
			if (Log.isLoggable(TAG, Log.DEBUG)) {
				Log.d(TAG,"远程接口返回状态：" + response.code());
			}
			resBody = response.body().string();
			if (Log.isLoggable(TAG, Log.DEBUG)) {
				Log.d(TAG,"响应内容：" + resBody);
			}
		}
		return resBody;
	}

	public static Response getResponse(String serverUrl) throws Exception {
		if (Log.isLoggable(TAG, Log.DEBUG)) {
			Log.d(TAG,"请求地址：" + serverUrl);
		}

		OkHttpClient client = new OkHttpClient.Builder()
				.connectionSpecs(Arrays.asList(ConnectionSpec.CLEARTEXT, ConnectionSpec.COMPATIBLE_TLS))
				.sslSocketFactory(sslSocketFactory(), trustX509Manager())
				.build();

		Request request = new Request.Builder()
				.url(serverUrl)
				.get()
				.build();
		return client.newCall(request).execute();
	}

	public static SSLSocketFactory sslSocketFactory() {
		try {
			SSLContext sslContext = SSLContext.getInstance("SSL");
			sslContext.init(null, trustManagers(), new SecureRandom());
			return sslContext.getSocketFactory();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}



	private static TrustManager[] trustManagers() {
		return new TrustManager[]{trustX509Manager()};
	}

	private static X509TrustManager trustX509Manager() {
		return new X509TrustManager() {
			@Override
			public void checkClientTrusted(X509Certificate[] chain, String authType) {
			}

			@Override
			public void checkServerTrusted(X509Certificate[] chain, String authType) {
			}

			@Override
			public X509Certificate[] getAcceptedIssuers() {
				return new X509Certificate[]{};
			}
		};
	}

	public static SSLSocketFactory defaultSslSocketFactory() throws Exception {
		if (null != sslSocketFactory) {
			return  sslSocketFactory;
		}
		return createSslSocketFactory();
	}

	private static SSLSocketFactory createSslSocketFactory() throws Exception {
		InputStream inStream = Application.getContext().getAssets().open("app_campusplus_com.crt");
		CertificateFactory cerFactory = CertificateFactory.getInstance("X.509");
		Certificate cer = cerFactory.generateCertificate(inStream);

		KeyStore kStore = KeyStore.getInstance("PKCS12");
		kStore.load(null, null);
		kStore.setCertificateEntry("trust", cer);

		KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		keyFactory.init(kStore, null);

		TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		trustFactory.init(kStore);

		SSLContext sslContext = SSLContext.getInstance("TLS");// SSL
		sslContext.init(keyFactory.getKeyManagers(), trustFactory.getTrustManagers(), new SecureRandom());

		return sslSocketFactory = sslContext.getSocketFactory();
	}
}
